package com.danke.lib.banner.widget.banner;

import android.content.Context;
import android.content.res.Resources;
import android.content.res.TypedArray;
import android.graphics.Color;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.GradientDrawable;
import android.util.AttributeSet;
import android.view.Gravity;
import android.view.View;
import android.view.animation.Interpolator;
import android.widget.ImageView;
import android.widget.LinearLayout;

import com.danke.lib.banner.R;
import com.danke.lib.banner.anim.BaseAnimator;
import com.danke.lib.banner.anim.WidthAnimator;

import java.util.ArrayList;

@SuppressWarnings("unchecked")
public abstract class BaseIndicatorBanner<E, T extends BaseIndicatorBanner<E, T>> extends BaseBanner<E, T> {
    public static final int STYLE_DRAWABLE_RESOURCE = 0;
    public static final int STYLE_CORNER_RECTANGLE = 1;

    private ArrayList<ImageView> mIndicatorViews = new ArrayList<>();
    private int mIndicatorStyle;
    private int mIndicatorWidth;
    private int mIndicatorWidthSelected;
    private int mIndicatorHeight;
    private int mIndicatorGap;
    private int mIndicatorCornerRadius;

    private Drawable mDrawableDefault;
    private Drawable mDrawableSelected;
    private int mColorDefault;
    private int mColorSelected;

    private Class<? extends BaseAnimator> mAnimClassDefault;
    private Class<? extends BaseAnimator> mAnimClassSelected;

    private LinearLayout mLlIndicators;

    public BaseIndicatorBanner(Context context) {
        this(context, null, 0);
    }

    public BaseIndicatorBanner(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public BaseIndicatorBanner(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);

        TypedArray ta = context.obtainStyledAttributes(attrs, R.styleable.BaseIndicatorBanner);
        mIndicatorStyle = ta.getInt(R.styleable.BaseIndicatorBanner_bb_indicatorStyle, STYLE_CORNER_RECTANGLE);
        mIndicatorWidth = ta.getDimensionPixelSize(R.styleable.BaseIndicatorBanner_bb_indicatorWidth, dp2px(6));
        mIndicatorWidthSelected = ta.getDimensionPixelSize(R.styleable.BaseIndicatorBanner_bb_indicatorWidthSelected, mIndicatorWidth);
        mIndicatorHeight = ta.getDimensionPixelSize(R.styleable.BaseIndicatorBanner_bb_indicatorHeight, dp2px(6));
        mIndicatorGap = ta.getDimensionPixelSize(R.styleable.BaseIndicatorBanner_bb_indicatorGap, dp2px(6));
        mIndicatorCornerRadius = ta.getDimensionPixelSize(R.styleable.BaseIndicatorBanner_bb_indicatorCornerRadius, dp2px(3));
        mColorDefault = ta.getColor(R.styleable.BaseIndicatorBanner_bb_indicatorColorDefault, Color.parseColor("#88ffffff"));
        mColorSelected = ta.getColor(R.styleable.BaseIndicatorBanner_bb_indicatorColorSelected, Color.parseColor("#ffffff"));

        int resDefault = ta.getResourceId(R.styleable.BaseIndicatorBanner_bb_indicatorResDefault, 0);
        int resSelected = ta.getResourceId(R.styleable.BaseIndicatorBanner_bb_indicatorResSelected, 0);
        ta.recycle();

        //create indicator container
        mLlIndicators = new LinearLayout(context);
        mLlIndicators.setGravity(Gravity.CENTER);

        setIndicatorRes(resDefault, resSelected);
    }

    @Override
    public View onCreateIndicator() {
        if (mIndicatorStyle == STYLE_CORNER_RECTANGLE) {//rectangle
            this.mDrawableDefault = getDrawable(mColorDefault, mIndicatorCornerRadius);
            this.mDrawableSelected = getDrawable(mColorSelected, mIndicatorCornerRadius);
        }

        int size = getData().size();
        mIndicatorViews.clear();

        mLlIndicators.removeAllViews();
        for (int i = 0; i < size; i++) {
            ImageView iv = new ImageView(mContext);
            iv.setImageDrawable(i == mCurrentPosition ? mDrawableSelected : mDrawableDefault);
            int width = i == mCurrentPosition ? mIndicatorWidthSelected : mIndicatorWidth;
            LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(width,
                    mIndicatorHeight);
            lp.leftMargin = i == 0 ? 0 : mIndicatorGap;
            mLlIndicators.addView(iv, lp);
            mIndicatorViews.add(iv);
        }

        setCurrentIndicator(mCurrentPosition);

        return mLlIndicators;
    }

    @Override
    public void setCurrentIndicator(int position) {
        for (int i = 0; i < mIndicatorViews.size(); i++) {
            mIndicatorViews.get(i).setImageDrawable(i == position ? mDrawableSelected : mDrawableDefault);
        }
        try {
            BaseAnimator animDefault = null;
            BaseAnimator animSelected = null;
            // 如果指示器选中和未选中时宽度不一样，则需要设置AnimClass
            if (mIndicatorWidth != mIndicatorWidthSelected) {
                animDefault = WidthAnimator.newInstance(mIndicatorWidth);
                animSelected = WidthAnimator.newInstance(mIndicatorWidthSelected);
            }
            if (mAnimClassSelected != null) {
                animSelected = mAnimClassSelected.newInstance();
            }
            if (mAnimClassDefault != null) {
                animDefault = mAnimClassDefault.newInstance();
            }
            if (animSelected != null) {
                if (position == mLastPosition) {
                    animSelected.playOn(mIndicatorViews.get(position));
                } else {
                    animSelected.playOn(mIndicatorViews.get(position));
                    if (animDefault == null) {
                        animSelected.interpolator(new ReverseInterpolator()).playOn(mIndicatorViews.get(mLastPosition));
                    } else {
                        animDefault.playOn(mIndicatorViews.get(mLastPosition));
                    }
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 设置显示样式,STYLE_DRAWABLE_RESOURCE or STYLE_CORNER_RECTANGLE
     */
    public T setIndicatorStyle(int indicatorStyle) {
        this.mIndicatorStyle = indicatorStyle;
        return (T) this;
    }

    /**
     * 设置显示宽度,单位dp,默认6dp
     */
    public T setIndicatorWidth(float indicatorWidth) {
        int value = dp2px(indicatorWidth);
        if (mIndicatorWidthSelected == mIndicatorWidth) {
            mIndicatorWidthSelected = value;
        }
        this.mIndicatorWidth = value;
        return (T) this;
    }

    /**
     * 设置选中态显示宽度
     */
    public T setIndicatorWidthSelected(float indicatorWidthSelected) {
        this.mIndicatorWidthSelected = dp2px(indicatorWidthSelected);
        return (T) this;
    }

    /**
     * 设置显示器高度,单位dp,默认6dp
     */
    public T setIndicatorHeight(float indicatorHeight) {
        this.mIndicatorHeight = dp2px(indicatorHeight);
        return (T) this;
    }

    /**
     * 设置两个显示器间距,单位dp,默认6dp
     */
    public T setIndicatorGap(float indicatorGap) {
        this.mIndicatorGap = dp2px(indicatorGap);
        return (T) this;
    }

    /**
     * 设置显示器选中颜色(for STYLE_CORNER_RECTANGLE),默认"#ffffff"
     */
    public T setIndicatorColorSelected(int colorSelected) {
        this.mColorSelected = colorSelected;
        return (T) this;
    }

    /**
     * 设置显示器未选中颜色(for STYLE_CORNER_RECTANGLE),默认"#88ffffff"
     */
    public T setIndicatorColorDefault(int colorDefault) {
        this.mColorDefault = colorDefault;
        return (T) this;
    }

    /**
     * 设置显示器圆角弧度(for STYLE_CORNER_RECTANGLE),单位dp,默认3dp
     */
    public T setIndicatorCornerRadius(float indicatorCornerRadius) {
        this.mIndicatorCornerRadius = dp2px(indicatorCornerRadius);
        return (T) this;
    }

    /**
     * 设置显示器选中以及未选中资源(for STYLE_DRAWABLE_RESOURCE)
     */
    public T setIndicatorRes(int resDefault, int resSelected) {
        try {
            if (mIndicatorStyle == STYLE_DRAWABLE_RESOURCE) {
                if (resSelected != 0) {
                    this.mDrawableSelected = getResources().getDrawable(resSelected);
                }
                if (resDefault != 0) {
                    this.mDrawableDefault = getResources().getDrawable(resDefault);
                }
            }
        } catch (Resources.NotFoundException e) {
            e.printStackTrace();
        }
        return (T) this;
    }

    /**
     * 设置显示器选中动画
     */
    public T setAnimClassSelected(Class<? extends BaseAnimator> animClassSelected) {
        this.mAnimClassSelected = animClassSelected;
        return (T) this;
    }

    /**
     * 设置显示器未选中动画
     */
    public T setAnimClassDefault(Class<? extends BaseAnimator> animClassDefault) {
        this.mAnimClassDefault = animClassDefault;
        return (T) this;
    }

    private class ReverseInterpolator implements Interpolator {
        @Override
        public float getInterpolation(float value) {
            return Math.abs(1.0f - value);
        }
    }

    private GradientDrawable getDrawable(int color, float raduis) {
        GradientDrawable drawable = new GradientDrawable();
        drawable.setCornerRadius(raduis);
        drawable.setColor(color);

        return drawable;
    }
}
